package org.game.module.datingbo.trigger;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sojoys.artifact.manager.PropManager;
import com.xiaoleilu.hutool.log.Log;
import com.xiaoleilu.hutool.log.LogFactory;
import com.xiaoleilu.hutool.util.ClassUtil;
import org.cfg.cache.DiscreteDataCfgCache;
import org.constant.DatingConstant;
import org.constant.DiscreteDataID;
import org.constant.DiscreteDataKey;
import org.game.constant.GameConstant;
import org.game.db.bean.CityDatingRecord;
import org.game.db.bean.Player;
import org.game.db.cache.CityDatingRecordCache;
import org.game.module.datingbo.DatingType;
import org.utils.TimeUtil;

import java.lang.reflect.Modifier;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 城市约会触发器（城市约会包括打工约会、出游约会、预定约会三种）
 * Created by fxf on 2018-3-14.
 */
public class CityDatingTriggerManager {

    static Log log = LogFactory.get();

    private static Map<Integer, CityDatingTrigger> cityDatingTriggerMap = Maps.newHashMap();

    static {
        cityDatingTriggerMap.clear();
        log.debug("----------------------------Scan Timing Dating Trigger Begin----------------------------");
        Set<Class<?>> scanClasses = ClassUtil.scanPackageBySuper(PropManager.get(GameConstant.SCAN_DATING_TRIGGER), CityDatingTrigger.class);
        for (Class scanClass : scanClasses) {
            if (scanClass.isInterface()) {
                continue;
            }
            if (Modifier.isAbstract(scanClass.getModifiers())) {
                continue;
            }
            Object handler = ClassUtil.newInstance(scanClass);
            DatingType annotation = (DatingType) scanClass.getAnnotation(DatingType.class);
            if (annotation == null)
                continue;
            int eventType = annotation.value();
            cityDatingTriggerMap.put(eventType, (CityDatingTrigger) handler);
            log.debug("Registry Dating Trigger：{}", handler.getClass().getName());
        }
        log.debug("----------------------------Scan Timing Dating Trigger End----------------------------");
    }

    private CityDatingTriggerManager() {
    }

    public static void refreshCityDating(Player player,Date now){
        List<CityDatingRecord> recordList = CityDatingRecordCache.me().getByPlayerId(player.getId());
        cityDatingTriggerMap.keySet().forEach(datingType->{
            List<CityDatingRecord> sameTypeList = recordList.stream()
                    .filter(record->record.getDatingType() == datingType)
                    .collect(Collectors.toList());
            cityDatingTriggerMap.get(datingType).refreshCityDating(player,sameTypeList,now);
        });
    }



    public static void trigger(Player player, Map<String,List<Integer>> timeFrame, Date now) {
        List<Integer> triggerTypeList = (List<Integer>) DiscreteDataCfgCache.me().getData(DiscreteDataID.DATING,DiscreteDataKey.TRIGGER_ORDER);
        for (int datingType:triggerTypeList){
            cityDatingTriggerMap.get(datingType).triggerDating(player, timeFrame,now);
        }
    }

    /**
     * 获取触发时段
     * 触发时段被所有城市约会共享，在同一触发时段只能触发一次任意类型的城市约会
     * P.S.目前打工约会、预定约会、出游约会的触发时间做成了统一的，如果策划需要改成每种时间不同，就把这个写到它们各自的触发类中去
     * @return
     */
    public static Map<String,List<Integer>> getTimeFrame(){
        Map<String,List<Integer>> timeFrameMap = Maps.newHashMap();
        Calendar now = Calendar.getInstance();
        now.set(Calendar.MILLISECOND,0);
        now.set(Calendar.SECOND,0);
        int index = 0;
        List<List<Integer>> triggerTimeFrameList = (List<List<Integer>>) DiscreteDataCfgCache.me().getData(DiscreteDataID.DATING, DiscreteDataKey.TRIGGER_FRAME);
        for (List<Integer> timeFrame : triggerTimeFrameList) {
            Calendar beginTime = TimeUtil.getCalendarByHourMinute(timeFrame.get(0),timeFrame.get(1));
            Calendar endTime = TimeUtil.getCalendarByHourMinute(timeFrame.get(2),timeFrame.get(3));

            if (beginTime.getTimeInMillis() <= now.getTimeInMillis() && endTime.getTimeInMillis() >= now.getTimeInMillis()){
                timeFrameMap.put(DatingConstant.TRIGGER_TIME,timeFrame);
                break;
            }
            index++;
        }
        if (timeFrameMap.size() > 0){
            List<List<Integer>> datingTimeFrameList = (List<List<Integer>>) DiscreteDataCfgCache.me().getData(DiscreteDataID.DATING, DiscreteDataKey.DATING_TIME_FRAME);
            timeFrameMap.put(DatingConstant.DATING_TIME,datingTimeFrameList.get(index));
        }
        return timeFrameMap;
    }

    public static List<Integer> getJustRefreshHour(){
        return (List<Integer>) DiscreteDataCfgCache.me().getData(DiscreteDataID.DATING,DiscreteDataKey.REFRESH_HOUR);
    }

    public static void testTrigger(Player player, Map<String,List<Integer>> timeFrame, Date now,int datingType){
        cityDatingTriggerMap.get(datingType).triggerDating(player, timeFrame,now);
    }
}
